﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
using Newtonsoft.Json;

namespace Kz.Telegram.Bot.Infrastructure.Helpers
{
    public class EncryptorHelper
    {
        public string sKey = string.Empty;
        public EncryptorHelper()
        {
            int[] numArray = new int[] { 0x7b, 0xea, 0xc3, 0xa5, 0xc9, 240, 0x8f, 0xc6 };
            foreach (int num in numArray)
            {
                sKey = sKey + ((char)num).ToString();
            }
        }

        /// <summary>
        /// MD5函数
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <returns>MD5结果</returns>
        public static string MD5(string str)
        {
            if (string.IsNullOrEmpty(str))
                return "";
            byte[] b = Encoding.GetEncoding("UTF-8").GetBytes(str);
            b = new MD5CryptoServiceProvider().ComputeHash(b);
            StringBuilder ret = new StringBuilder();
            for (int i = 0; i < b.Length; i++)
                ret.Append(b[i].ToString("x").PadLeft(2, '0'));
            return ret.ToString();
        }

        public static string Md5Hash(string strContent)
        {
            byte[] bytContent = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(strContent));
            string strResult = "";
            for (int i = 0; i < bytContent.Length; i++)
            {
                strResult += bytContent[i].ToString("x").PadLeft(2, '0');
            }
            return strResult;
        }

        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="pToEncrypt"></param>
        /// <returns></returns>
        public string Encrypt_DES(string pToEncrypt)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] bytes = Encoding.Default.GetBytes(pToEncrypt);
            provider.Key = Encoding.ASCII.GetBytes(sKey);
            provider.IV = Encoding.ASCII.GetBytes(sKey);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            foreach (byte num in stream.ToArray())
            {
                builder.AppendFormat("{0:X2}", num);
            }
            builder.ToString();
            return builder.ToString();
        }

        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="pToDecrypt"></param>
        /// <returns></returns>
        public string Decrypt_DES(string pToDecrypt)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] buffer = new byte[pToDecrypt.Length / 2];
            for (int i = 0; i < pToDecrypt.Length / 2; i++)
            {
                int num2 = Convert.ToInt32(pToDecrypt.Substring(i * 2, 2), 0x10);
                buffer[i] = (byte)num2;
            }
            provider.Key = Encoding.ASCII.GetBytes(sKey);
            provider.IV = Encoding.ASCII.GetBytes(sKey);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(), CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            return Encoding.Default.GetString(stream.ToArray());
        }

        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="pToEncrypt">明文</param>
        /// <returns></returns>
        public static string DesEncrypt(string key, string pToEncrypt)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] bytes = Encoding.Default.GetBytes(pToEncrypt);
            des.Key = Encoding.ASCII.GetBytes(key);
            des.IV = Encoding.ASCII.GetBytes(key);
            MemoryStream ms = new MemoryStream();
            CryptoStream stream = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            stream.Write(bytes, 0, bytes.Length);
            stream.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            foreach (byte num in ms.ToArray())
            {
                builder.AppendFormat("{0:X2}", num);
            }
            return builder.ToString();
        }

        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="pToDecrypt">密文</param>
        /// <returns></returns>
        public static string DesDecrypt(string key, string pToDecrypt)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] buffer = new byte[pToDecrypt.Length / 2];
            for (int i = 0; i < pToDecrypt.Length / 2; i++)
            {
                int num2 = Convert.ToInt32(pToDecrypt.Substring(i * 2, 2), 0x10);
                buffer[i] = (byte)num2;
            }
            provider.Key = Encoding.ASCII.GetBytes(key);
            provider.IV = Encoding.ASCII.GetBytes(key);
            MemoryStream ms = new MemoryStream();
            CryptoStream stream = new CryptoStream(ms, provider.CreateDecryptor(), CryptoStreamMode.Write);
            stream.Write(buffer, 0, buffer.Length);
            stream.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            return Encoding.Default.GetString(ms.ToArray());
        }

        /// <summary>
        /// base64加密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        public static string Encrypt_Base64(string Message)
        {
            byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(Message);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// base64解密
        /// </summary>
        /// <param name="Message"></param>
        /// <returns></returns>
        public static string Decrypt_Base64(string Message)
        {
            byte[] bytes = Convert.FromBase64String(Message);
            return Encoding.GetEncoding("UTF-8").GetString(bytes);
        }

        /// <summary>
        /// AES-256-ECB解密
        /// </summary>
        /// <param name="inputdata"></param>
        /// <param name="aesKey"></param>
        /// <returns></returns>
        public static string AES256ECBDecrypt(string inputdata, string aesKey)
        {
            try
            {
                byte[] encryptedData = Convert.FromBase64String(inputdata);
                RijndaelManaged rijndaelCipher = new RijndaelManaged
                {
                    Key = Encoding.UTF8.GetBytes(aesKey),
                    Mode = CipherMode.ECB,
                    Padding = PaddingMode.PKCS7
                };

                ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
                byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
                string result = Encoding.UTF8.GetString(plainText);

                return result;
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static string MD5To16(string str)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(str)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2.ToLower();
        }

        /// <summary>
        /// 基于Sha1的自定义加密字符串方法：输入一个字符串，返回一个由40个字符组成的十六进制的哈希散列（字符串）。
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns>加密后的十六进制的哈希散列（字符串）</returns>
        public static string Sha1(string str)
        {
            var buffer = Encoding.UTF8.GetBytes(str);
            var data = SHA1.Create().ComputeHash(buffer);

            var sb = new StringBuilder();
            foreach (var t in data)
            {
                sb.Append(t.ToString("X2"));
            }
            return sb.ToString();
        }
    }
}
